﻿#If RO_SPECIFICS = True Then
'// ========================================================================= '
'// ------------------------------------------------------------------------- '
'//!				\file		CM_RO_Tables.vb
'			        \date		june 2010
'			        \author		TNick
'
'			        \brief		
'
'
'   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'   This file is considered universal knowledge. No restrictions
'   are imposed; use as you see fit.
'   Please read ReadMe.txt and Licence.txt in root folder
'   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'
'   
'
'// ------------------------------------------------------------------------- '
'// ========================================================================= '
'//
'//
'//
'//
'//  IMPORTS     ------------------------------------------------------------ '
#Region "Imports"

Imports System
Imports System.IO
Imports Microsoft.Win32
Imports System.Xml.Serialization

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Customization
Imports Autodesk.AutoCAD.PlottingServices
Imports Autodesk.AutoCAD.Colors

#End Region
'//  IMPORTS     ============================================================ '
'//
'//
'//
'//
'//  DEFINITIONS    --------------------------------------------------------- '
<Assembly: CommandClass(GetType(CM_RO_Tables))> 



#Region "Public Structures"

'// --------------------------------------------------------------------- '
'// advanced properties
<Serializable()> _
Public Structure PADADV
    '// ratio for Anexa, title and scale
    Public dTxR_Anexa As Double
    Public dTxR_Title As Double
    Public dTxR_Scale As Double
    '// space left empty arroud text
    Public dTxR_Al As Double
    '// ratio: single and double rows in tables
    Public dRoR_1 As Double
    Public dRoR_2 As Double
    '// ratio: columns in first table (last as difference)
    Public dClR_Top_1 As Double
    Public dCLR_Top_2 As Double
    Public dClR_Top_3 As Double
    '// ratio: columns in second table (last as difference)
    Public dClR_Mid_1 As Double
    Public dClR_Mid_2 As Double
    Public dClR_Mid_3 As Double
    Public dClR_Mid_4 As Double
    '// ratio: columns in third table (last as difference)
    Public dClR_Btm_Idx As Double
    Public dCLR_Btm_Coord As Double
    Public dClR_Btm_Sep As Double
    '// ratio: minimum size for Bottom table
    Public dBtm_MinH As Double
    '// borders
    Public dB_Left As Double
    Public dB_Right As Double
    Public dB_Top As Double
    Public dB_Bottom As Double
    '// horizontal and vertical distance (alignment) for table
    Public dB_Al_H As Double
    Public dB_Al_V As Double
    '// the width; if set to 0, implies smart calculation; otherwise mm
    Public dWidth As Double
    '// the name of the one that makes this paper
    Public sExecname As String
    '// data of creation; leave empty to auto-generate
    Public sData As String

End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'// information about a parcel recorded in a PAD
<Serializable()> _
Public Structure PADPARC
    Public Categ As String
    Public Name As String
    Public Supr As String
    Public Tip As String
    Public ValImp As String
End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'// information about a building recorded in a PAD
<Serializable()> _
Public Structure PADCONST
    Public Categ As String
    Public Code As String
    Public Supr As String
    Public Tip As String
    Public ValImp As String
End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'// information about a paper (layout)
<Serializable()> _
Public Structure LAYSTG
    Public Printer As String
    Public Format As String
    Public Overwr As Boolean
    Public Po As Boolean
    Public Name As String
    Public TextH As Double
    Public Ly_Tbl As String
    Public Ly_Var As String
    Public Ly_Vp As String
    '// printable area auto-extracted
    'Public dPrnMg_L As Double
    'Public dPrnMg_R As Double
    'Public dPrnMg_T As Double
    'Public dPrnMg_B As Double
End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'// a point used in PAD; has name, Noth and East
<Serializable()> _
Public Structure PADCRD
    Public PtName As String
    Public dN As Double
    Public dE As Double
End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'//the structure accumulates all the data refering to a PAD
<Serializable()> _
Public Structure PADDATA
    <NonSerialized()> _
    Public src_file As String

    Public ppr As LAYSTG
    <XmlArray(ElementName:="Parcels", _
         IsNullable:=True)> _
    Public Parcels() As PADPARC
    <XmlArray(ElementName:="Constr", _
         IsNullable:=True)> _
    Public Constr() As PADCONST
    <XmlArray(ElementName:="Coord", _
         IsNullable:=True)> _
    Public Coord() As PADCRD
    Public adv As PADADV
    Public Address As String
    Public CF As String
    Public NrCad As String
    Public SuprAct As String
    Public SuprMas As String
    Public UAT As String
    Public CoordF_XY As String
    Public CoordF_Z As String
End Structure
'// ===================================================================== '


'// --------------------------------------------------------------------- '
'// paper properties; brings together ISO names and sizes
Public Structure PPRPRP
    Public sName As String
    Public iW As Integer
    Public iH As Integer
    Public Sub New(ByRef asNm As String, ByVal aiW As Integer, ByVal aiH As Integer)
        sName = asNm
        iW = aiW
        iH = aiH
    End Sub
End Structure
'// ===================================================================== '


'// --------------------------------------------------------------------- '
'// defines the settings for this module
Public Structure ROTBL_STG

    Public PadStg As PADDATA

End Structure
'// ===================================================================== '



#End Region



'//  DEFINITIONS    ========================================================= '
'//
'//
'//
'//
'//  DATA    ---------------------------------------------------------------- '


'//  DATA    ================================================================ '
'//
'//
'//
'//
'//  CLASS    --------------------------------------------------------------- '

Public Class CM_RO_Tables
    Inherits CModule


    '// holds the objects that compose the PAD
    Private Structure PADOBJ
        Dim oiANX As ObjectId
        Dim oiTITLE As ObjectId
        Dim oiSCALE As ObjectId
        Dim oiTBTOP As ObjectId
        Dim oiVP As ObjectId
        Dim oiTBMID As ObjectId
        Dim oiTBBTM As ObjectId
    End Structure


    '// --------------------------------------------------------------------- '
    '// DATA
#Region "Public Constants"
    '// name as displayed in various places
    Public Const sAPPNAME As String = "(RO)Tabele"
    '// version as displayed in various places
    Public Const sAPPVER As String = "1.0.0.0"

    '// Command. Brings up the settings dialog
    Public Const sCMD_SETTINGS As String = "TNIK_ROTBL_STG"
    '// Command. Start GUI for PAD
    Public Const sCMD_PAD As String = "TNIK_ROTBL_PAD"
    '// Command. Start GUI for PS
    Public Const sCMD_PS As String = "TNIK_ROTBL_PS"


    '// types of papers (offsets in array)
    Public Enum EPPRTY
        A0 = 0
        A1 = 1
        A2 = 2
        A3 = 3
        A4 = 4

    End Enum
#End Region

#Region "Public Data"
    '// short description
    Public sAPPTIP As String
    '// this is where the settings are stored durring run-time
    Public Shared Stgs As ROTBL_STG


    '// structure that hosts ISO page types and dimensions
    Public Shared PaperTy() As PPRPRP = { _
        New PPRPRP("A0", 841, 1189), _
        New PPRPRP("A1", 594, 841), _
        New PPRPRP("A2", 420, 594), _
        New PPRPRP("A3", 297, 420), _
        New PPRPRP("A4", 210, 297), _
        New PPRPRP("A5", 148, 210), _
        New PPRPRP("A6", 105, 148), _
        New PPRPRP("A7", 74, 105), _
        New PPRPRP("A8", 52, 74), _
        New PPRPRP("A9", 37, 52), _
        New PPRPRP("A10", 26, 37), _
        New PPRPRP("B0", 1000, 1414), _
        New PPRPRP("B1", 707, 1000), _
        New PPRPRP("B2", 500, 707), _
        New PPRPRP("B3", 353, 500), _
        New PPRPRP("B4", 250, 353), _
        New PPRPRP("B5", 176, 250), _
        New PPRPRP("B6", 125, 176), _
        New PPRPRP("B7", 88, 125), _
        New PPRPRP("B8", 62, 88), _
        New PPRPRP("B9", 44, 62), _
        New PPRPRP("B10", 31, 44), _
        New PPRPRP("C0", 917, 1297), _
        New PPRPRP("C1", 648, 917), _
        New PPRPRP("C2", 458, 648), _
        New PPRPRP("C3", 324, 458), _
        New PPRPRP("C4", 229, 324), _
        New PPRPRP("C5", 162, 229), _
        New PPRPRP("C6", 114, 162), _
        New PPRPRP("C7", 81, 114), _
        New PPRPRP("C8", 57, 81), _
        New PPRPRP("C9", 40, 57), _
        New PPRPRP("C10", 28, 40) _
    }

    '// lists strings in TX in english
    Public Shared sMonths() As String = New String() { _
            "ianuarie", _
            "februarie", _
            "martie", _
            "aprilie", _
            "mai", _
            "iunie", _
            "iulie", _
            "august", _
            "septembrie", _
            "octombrie", _
            "noiembrie", _
            "decembrie" _
    }

#End Region
    '// ===================================================================== '

    '// ===================================================================== '



#Region "Private general purpose Functions"


    '// --------------------------------------------------------------------- '
    '// This function saves current settings
    Private Shared Sub SaveSett()
        Try
            If (String.IsNullOrEmpty(Stgs.PadStg.src_file)) Then
                Stgs.PadStg.src_file = CApp.sAppPath & "Misc\Pad.xml"
                Save_Pad_To_File(Stgs.PadStg, Stgs.PadStg.src_file)
            End If
            CSett.SaveStg(sAPPNAME, "Stgs.PAD.src_file", Stgs.PadStg.src_file)
        Catch ex As System.Exception
            Debug.Print("RoTables SaveSett Exception " & ex.Message)
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
    '// This function loads current settings
    Private Shared Sub GetSett()
        Try
            Stgs.PadStg.src_file = CSett.GetStrStg(sAPPNAME, "Stgs.PAD.src_file", "")
            If (System.IO.File.Exists(Stgs.PadStg.src_file)) Then
                Load_Pad_From_File(Stgs.PadStg, Stgs.PadStg.src_file)
            ElseIf (System.IO.File.Exists(CApp.sAppPath & "Misc\Pad.xml")) Then
                Stgs.PadStg.src_file = CApp.sAppPath & "Misc\Pad.xml"
                Load_Pad_From_File(Stgs.PadStg, Stgs.PadStg.src_file)
            Else
                Stgs.PadStg.adv.dTxR_Anexa = 0.9
                Stgs.PadStg.adv.dTxR_Title = 1.2
                Stgs.PadStg.adv.dTxR_Scale = 1
                Stgs.PadStg.adv.dTxR_Al = 0.1
                Stgs.PadStg.adv.dRoR_1 = 1.3
                Stgs.PadStg.adv.dRoR_2 = 1.3
                Stgs.PadStg.adv.dClR_Top_1 = 10
                Stgs.PadStg.adv.dCLR_Top_2 = 10
                Stgs.PadStg.adv.dClR_Top_3 = 8
                Stgs.PadStg.adv.dClR_Mid_1 = 10
                Stgs.PadStg.adv.dClR_Mid_2 = 10
                Stgs.PadStg.adv.dClR_Mid_3 = 10
                Stgs.PadStg.adv.dClR_Mid_4 = 10
                Stgs.PadStg.adv.dClR_Btm_Idx = 6
                Stgs.PadStg.adv.dCLR_Btm_Coord = 8
                Stgs.PadStg.adv.dClR_Btm_Sep = 0.2
                Stgs.PadStg.adv.dBtm_MinH = 80
                Stgs.PadStg.adv.dB_Left = 20
                Stgs.PadStg.adv.dB_Right = 10
                Stgs.PadStg.adv.dB_Top = 10
                Stgs.PadStg.adv.dB_Bottom = 10
                Stgs.PadStg.adv.dB_Al_H = 0.1
                Stgs.PadStg.adv.dB_Al_V = 0.1
                Stgs.PadStg.adv.dWidth = 210 - 30
                Stgs.PadStg.adv.sData = ""
                Stgs.PadStg.adv.sExecname = "?"
            End If
        Catch ex As System.Exception
            Debug.Print("RoTables GetSett Exception " & ex.Message)
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
    '// This function shows current settings
    Private Shared Function PrintStg(ByRef lcStg As ROTBL_STG) As String
        Return (vbNewLine & CMain._T(TX.CSTG) & sAPPNAME & ": " & vbNewLine & _
 _
              CMain._T(TX.MODEL) & ":" & vbNewLine & _
          vbNewLine & vbNewLine)

    End Function
    '// ===================================================================== '


#End Region

#Region "Common interface" ' -----------------------

    '// --------------------------------------------------------------------- '
    '// a new instance is created
    Public Sub New()
        Try
            sAPPTIP = "Tabele specifice"
            Return
        Catch ex As System.Exception
            CMain.DebugException(ex)
            Return
        End Try
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is asked to terminate
    Public Overrides Function Terminate() As Boolean
        Try
            SaveSett()
            Return True
        Catch ex As System.Exception
            CMain.DebugException(ex)
            Return False
        End Try
    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is informed about application start-up
    Public Shared Sub DoPrereq()
        Try
            ' this function is called at application start-up in order to 
            ' allow applications to do any prerequisites
            ' there is no instance of this class at this time
            GetSett()
        Catch ex As System.Exception
            CMain.DebugException(ex)
        End Try
        Return
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// create the user interface for this module
    Public Shared Sub DoCUI( _
     ByRef pcs As CustomizationSection, _
     ByRef mg As MacroGroup)
        ' this function is called when a CUI is builded in order to
        ' allow any application specifics
        Try
#If HARDCORE_CUI Then
            If CApp.cuiCl Is Nothing Then Exit Try
            CApp.cuiCl.AddMacro(sCMD_SETTINGS, "ROTBL_Settings")
            CApp.cuiCl.AddMacro(sCMD_PAD, "ROTBL_Pad")
            CApp.cuiCl.AddMacro(sCMD_PS, "ROTBL_Ps")

            CApp.cuiCl.AddToolbar( _
                sAPPNAME, _
                Application.MainWindow.Location.X, _
                100 + MIDS.RO_TABLE * 30)
            CApp.cuiCl.AddToolbarBtn("PAD", sCMD_PAD)
            CApp.cuiCl.AddToolbarBtn("Plan de Situatie", sCMD_PS)
            CApp.cuiCl.AddToolbarSep()
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.SETTINGS), sCMD_SETTINGS)

#Else

			Dim mm1 As MenuMacro = Nothing
			mm1 = New MenuMacro(mg, sCMD_PAD, "^C^C" & sCMD_PAD, "ID_" & sCMD_PAD)
			mm1 = New MenuMacro(mg, sCMD_PS, "^C^C" & sCMD_PS, "ID_" & sCMD_PS)
			mm1 = New MenuMacro(mg, sCMD_SETTINGS, "^C^C" & sCMD_SETTINGS, "ID_" & sCMD_SETTINGS)


			Dim tbBtn As ToolbarButton = Nothing
			Dim newTb As Toolbar = New Toolbar(sAPPNAME, pcs.MenuGroup)
			newTb.ElementID = "EID_TNIK_RoTbl"
			newTb.ToolbarOrient = ToolbarOrient.floating
			newTb.ToolbarVisible = ToolbarVisible.show
            newTb.XCoordinate = Application.MainWindow.Location.X
            newTb.YCoordinate = 100 + MIDS.RO_TABLE * 30

			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = "PAD"
			tbBtn.MacroID = "ID_" & sCMD_PAD
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = "Plan de Situatie"
			tbBtn.MacroID = "ID_" & sCMD_PS
			tbBtn = New ToolbarButton(newTb, -1) ' separator
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.SETTINGS)
			tbBtn.MacroID = "ID_" & sCMD_SETTINGS

#End If
        Catch ex As System.Exception
            CMain.DebugException(ex)
        End Try
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is asked to tell it's name
    Public Shared Function GetName() As String
        Return sAPPNAME
    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is asked to tell about itself
    Public Shared Function GetDescription() As String
        Dim sOut As String = sAPPNAME
        Try
            Dim cIni As New IniWork(CApp.sAppPath & CMain.APPSTG)
            If cIni.HasErrors = True Then Exit Try
            sOut = cIni.Read(sAPPNAME, CMain.DESCRKEY & _
                             CMain.eAppLang.ToString, sAPPNAME)
        Catch ex As System.Exception
            CMain.DebugException(ex)
        End Try
        Return sOut
    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is asked to tell about itself
    Public Shared Sub GetInfos(ByRef sName As String, ByRef sVer As String, ByRef sTip As String)
        sName = sAPPNAME
        sVer = sAPPVER
        sTip = "Utilitar pentru crearea de tabele specifice"
    End Sub
    '// ===================================================================== '

#End Region

#Region "GENERIC FUNCTIONS"

    '// --------------------------------------------------------------------- '
    '// find the type of a paper type based on it's name
    Private Shared Function GetPprType(ByRef sCk As String) As Integer
        For i As Integer = 0 To PaperTy.Length - 1
            If (sCk.ToUpper() = PaperTy(i).sName) Then
                Return i
            ElseIf (sCk.ToUpper() Like PaperTy(i).sName & "*") Then
                Return i
            ElseIf (sCk.ToUpper() Like "*" & PaperTy(i).sName) Then
                Return i
            ElseIf (sCk.ToUpper() Like "*" & PaperTy(i).sName & "*") Then
                Return i
            End If
        Next
        Return 4 '// A4
    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// The layout create part was found at 
    '// http://www.acadnetwork.com/profile/user-2/area,showposts/
    '// no author was evident. Thank you.
    Public Shared Function Create_lAY( _
        ByRef acDoc As Document, _
        ByRef acTrans As Transaction, _
        ByRef stgly As LAYSTG) _
    As Boolean

        Dim bRet As Boolean = False
        Dim acPlSet As PlotSettings = Nothing

        Try
            '// --------------------------------------------------
            '// enshure that required layers are present
            Dim acLy As LayerTableRecord = Nothing
            Dim acLyTbl As LayerTable = DirectCast( _
                acTrans.GetObject(acDoc.Database.LayerTableId, _
                               OpenMode.ForWrite),  _
                LayerTable)
            If (acLyTbl.Has(stgly.Ly_Tbl) = False) Then
                acLy = New LayerTableRecord()
                acLy.Name = stgly.Ly_Tbl
                acLy.Color = Color.FromColorIndex(ColorMethod.ByAci, 20)
                acLyTbl.Add(acLy)
                acTrans.AddNewlyCreatedDBObject(acLy, True)
            End If
            If (acLyTbl.Has(stgly.Ly_Var) = False) Then
                acLy = New LayerTableRecord()
                acLy.Name = stgly.Ly_Var
                acLy.Color = Color.FromColorIndex(ColorMethod.ByAci, 151)
                acLyTbl.Add(acLy)
                acTrans.AddNewlyCreatedDBObject(acLy, True)
            End If
            If (acLyTbl.Has(stgly.Ly_Vp) = False) Then
                acLy = New LayerTableRecord()
                acLy.Name = stgly.Ly_Vp
                acLy.Color = Color.FromColorIndex(ColorMethod.ByAci, 83)
                acLyTbl.Add(acLy)
                acTrans.AddNewlyCreatedDBObject(acLy, True)
            End If
            '// \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\



            '// --------------------------------------------------
            '// check to see if this layout is already present
            Dim layoutId As ObjectId
            Dim acLayout As Layout

            Dim layouts As DBDictionary = DirectCast( _
                acTrans.GetObject(acDoc.Database.LayoutDictionaryId, _
                                  OpenMode.ForWrite),  _
                DBDictionary)
            If (layouts.Contains(stgly.Name)) Then
                '// see what instructions has the user for this case
                If (stgly.Overwr = True) Then
                    LayoutManager.Current.DeleteLayout(stgly.Name)
                Else
                    Dim i As Integer = 1
                    While (layouts.Contains( _
                           stgly.Name & "(" & i.ToString & ")"))
                        i = i + 1
                    End While
                    stgly.Name = stgly.Name & "(" & i.ToString & ")"
                End If
            End If
            '// \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

            '// --------------------------------------------------
            ' Create and activate the new layout
            layoutId = _
                LayoutManager.Current.CreateLayout(stgly.Name)
            LayoutManager.Current.CurrentLayout = stgly.Name

            ' Get the PlotInfo from the layout
            acLayout = DirectCast( _
                acTrans.GetObject(layoutId, _
                             OpenMode.ForWrite),  _
                Layout)

            Dim acPlInfo As PlotInfo
            acPlInfo = New PlotInfo()
            acPlInfo.Layout = acLayout.ObjectId

            ' Get a copy of the PlotSettings from the layout
            acPlSet = New PlotSettings(acLayout.ModelType)
            acPlSet.CopyFrom(acLayout)

            ' save paper margins
            'stgly.dPrnMg_L = acPlSet.PlotPaperMargins.MinPoint.X
            'stgly.dPrnMg_R = acPlSet.PlotPaperMargins.MaxPoint.X
            'stgly.dPrnMg_T = acPlSet.PlotPaperMargins.MaxPoint.Y
            'stgly.dPrnMg_B = acPlSet.PlotPaperMargins.MinPoint.Y

            Dim acPlSetVdr As PlotSettingsValidator = _
                PlotSettingsValidator.Current
            acPlSetVdr.SetPlotConfigurationName(acPlSet, stgly.Printer, stgly.Format)
            acPlSetVdr.SetPlotType(acPlSet, Autodesk.AutoCAD.DatabaseServices.PlotType.Layout)
            acPlSetVdr.SetUseStandardScale(acPlSet, True)
            acPlSetVdr.SetPlotPaperUnits(acPlSet, PlotPaperUnit.Millimeters)
            acPlSetVdr.SetStdScaleType(acPlSet, StdScaleType.StdScale1To1)
            If (stgly.Po = True) Then
                acPlSetVdr.SetPlotRotation(acPlSet, Autodesk.AutoCAD.DatabaseServices.PlotRotation.Degrees000)
            Else
                acPlSetVdr.SetPlotRotation(acPlSet, Autodesk.AutoCAD.DatabaseServices.PlotRotation.Degrees090)
            End If
            'acPlSetVdr.SetCurrentStyleSheet(acPlSet, "Danisoft.ctb")

            acLayout.CopyFrom(acPlSet)
            '// \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

            acDoc.Editor.Regen()
            bRet = True
        Catch ex As System.Exception
            CMain.DebugException(ex)
            bRet = False
        Finally
            If (acPlSet IsNot Nothing) Then
                acPlSet.Dispose()
            End If
        End Try
        Return bRet
    End Function
    '// ===================================================================== '

#End Region


#Region "P  A  D"

    '// --------------------------------------------------------------------- '
    '// Creates PAD graphical components
    Private Shared Function Create_PAD_Comp( _
        ByRef acBlkTblRec As BlockTableRecord, _
        ByRef acTrans As Transaction, _
        ByRef sIn As PADDATA, _
        ByRef obj As PADOBJ) As Boolean

        Dim bRet As Boolean
        Dim acText As DBText = Nothing
        Dim acTbl As Table = Nothing
        Dim Cellreg As TableRegion

        Dim dDbl1 As Double
        Dim dDbl2 As Double

        Dim i As Integer, j As Integer
        Dim iRows As Integer
        Dim iRwExc As Integer
        Dim iRwConf As Integer
        Dim dWUsable As Double
        Dim tbAlH As Double = sIn.adv.dB_Al_H * sIn.ppr.TextH
        Try

            '// find the viewport
            Dim acVp As Viewport = Nothing
            i = 0
            For Each obj.oiVP In acBlkTblRec
                Dim acDbE As DBObject
                acDbE = acTrans.GetObject(obj.oiVP, OpenMode.ForRead)
                If TypeOf acDbE Is Viewport Then
                    If i = 0 Then
                        i = 1
                    Else
                        acVp = DirectCast(acDbE, Viewport)
                        GoTo VpFound
                    End If
                End If
            Next
            '// auto-generated viewport was not found
            acVp = New Viewport()
            acBlkTblRec.AppendEntity(acVp)
            acTrans.AddNewlyCreatedDBObject(acVp, True)
VpFound:
            acVp.UpgradeOpen()
            acVp.Layer = sIn.ppr.Ly_Vp
            acVp.CenterPoint = New Point3d(0, 0, 0)
            acVp.Width = 100
            acVp.Height = 100
            acVp = Nothing

            dWUsable = sIn.adv.dWidth - sIn.adv.dB_Left - sIn.adv.dB_Right - tbAlH*2
            '// refers to last table
            If (sIn.Coord Is Nothing) Then
                iRows = 4
            Else
                iRows = sIn.Coord.Length
            End If
            '// compute number of coordinate places
            If (iRows < 8) Then
                '// sanity checks
                If (dWUsable <= (sIn.adv.dClR_Btm_Idx + _
                                      sIn.adv.dCLR_Btm_Coord * 2) * _
                                  sIn.ppr.TextH) Then
                    dWUsable = (sIn.adv.dClR_Btm_Idx + _
                                      sIn.adv.dCLR_Btm_Coord * 4) * _
                                  sIn.ppr.TextH
                End If
            Else
                If (iRows Mod 2) = 1 Then
                    iRows = iRows + 1
                End If
                If (dWUsable <= (sIn.adv.dClR_Btm_Idx * 2 + _
                                      sIn.adv.dCLR_Btm_Coord * 4 + _
                                    sIn.adv.dClR_Btm_Sep) * _
                                  sIn.ppr.TextH) Then
                    dWUsable = (sIn.adv.dClR_Btm_Idx * 2 + _
                                      sIn.adv.dCLR_Btm_Coord * 6 + _
                                    sIn.adv.dClR_Btm_Sep) * _
                                  sIn.ppr.TextH
                End If
            End If

            '// sanity checks
            If (dWUsable <= (sIn.adv.dClR_Top_1 + _
                                  sIn.adv.dCLR_Top_2 + _
                                  sIn.adv.dClR_Top_3) * _
                                  sIn.ppr.TextH) Then
                dWUsable = (sIn.adv.dClR_Top_1 * 2 + _
                                  sIn.adv.dCLR_Top_2 + _
                                  sIn.adv.dClR_Top_3) * _
                                  sIn.ppr.TextH
            End If
            If (dWUsable <= (sIn.adv.dClR_Mid_1 + _
                                  sIn.adv.dClR_Mid_2 + _
                                  sIn.adv.dClR_Mid_3 + _
                                  sIn.adv.dClR_Mid_4) * _
                                  sIn.ppr.TextH) Then
                dWUsable = (sIn.adv.dClR_Mid_1 * 2 + _
                                  sIn.adv.dClR_Mid_2 + _
                                  sIn.adv.dClR_Mid_3 + _
                                  sIn.adv.dClR_Mid_4) * _
                                  sIn.ppr.TextH
            End If





            '// Anexa
            acText = New DBText()
            acText.SetDatabaseDefaults()
            acText.TextString = "Anexa ??"
            acText.Position = New Point3d(0, 100, 0)
            acText.Height = sIn.ppr.TextH * sIn.adv.dTxR_Anexa
            acText.Layer = sIn.ppr.Ly_Var
            acBlkTblRec.AppendEntity(acText)
            acTrans.AddNewlyCreatedDBObject(acText, True)
            obj.oiANX = acText.ObjectId
            acText = Nothing

            '// Main Title
            acText = New DBText()
            acText.SetDatabaseDefaults()
            acText.TextString = "PLAN DE AMPLASAMENT SI DELIMITARE A IMOBILULUI"
            acText.Position = New Point3d(0, 90, 0)
            acText.Height = sIn.ppr.TextH * sIn.adv.dTxR_Title
            acText.Layer = sIn.ppr.Ly_Var
            acBlkTblRec.AppendEntity(acText)
            acTrans.AddNewlyCreatedDBObject(acText, True)
            obj.oiTITLE = acText.ObjectId
            acText = Nothing

            '// Scale
            acText = New DBText()
            acText.SetDatabaseDefaults()
            acText.TextString = "Scara 1:"
            acText.Position = New Point3d(0, 80, 0)
            acText.Height = sIn.ppr.TextH * sIn.adv.dTxR_Scale
            acText.Layer = sIn.ppr.Ly_Var
            acBlkTblRec.AppendEntity(acText)
            acTrans.AddNewlyCreatedDBObject(acText, True)
            obj.oiSCALE = acText.ObjectId
            acText = Nothing

            '// Top table
            If (sIn.NrCad Is Nothing) Then
                sIn.NrCad = ""
            End If
            If (sIn.SuprMas Is Nothing) Then
                sIn.SuprMas = ""
            End If
            If (sIn.Address Is Nothing) Then
                sIn.Address = ""
            End If
            If (sIn.CF Is Nothing) Then
                sIn.CF = ""
            End If
            If (sIn.UAT Is Nothing) Then
                sIn.UAT = ""
            End If
            acTbl = New Table
            acTbl.SetDatabaseDefaults()
            acTbl.IsHeaderSuppressed = True
            acTbl.IsTitleSuppressed = True
            acTbl.NumRows = 3
            acTbl.NumColumns = 4
            For i = 0 To 2
                For j = 0 To 3
                    acTbl.SetTextHeight(i, j, sIn.ppr.TextH)
                    acTbl.SetAlignment(i, j, CellAlignment.MiddleCenter)
                Next
                acTbl.SetRowHeight(i, sIn.ppr.TextH * sIn.adv.dRoR_1)
            Next
            acTbl.SetColumnWidth(0, sIn.ppr.TextH * sIn.adv.dClR_Top_1)
            acTbl.SetColumnWidth(1, sIn.ppr.TextH * sIn.adv.dCLR_Top_2)
            acTbl.SetColumnWidth(2, sIn.ppr.TextH * sIn.adv.dClR_Top_3)
            acTbl.SetColumnWidth(3, dWUsable - _
                                 (sIn.adv.dClR_Top_1 + _
                                  sIn.adv.dCLR_Top_2 + _
                                  sIn.adv.dClR_Top_3) * _
                                  sIn.ppr.TextH)

            acTbl.Position = New Point3d(0, 70, 0)
            acTbl.Layer = sIn.ppr.Ly_Tbl


            '// special format for address
            Cellreg = New TableRegion(1, 2, 1, 3)
            acTbl.MergeCells(Cellreg)
            Cellreg = New TableRegion(0, 2, 0, 3)
            acTbl.MergeCells(Cellreg)
            acTbl.SetAlignment(0, 2, CellAlignment.MiddleLeft)
            acTbl.SetAlignment(1, 2, CellAlignment.MiddleLeft)


            '// fill it in
            acTbl.SetTextString(0, 0, "Nr. cad.")
            acTbl.SetTextString(0, 1, "Suprafata mas. (mp)")
            acTbl.SetTextString(0, 2, " Adresa imobilului")
            acTbl.SetTextString(1, 0, sIn.NrCad)
            acTbl.SetTextString(1, 1, sIn.SuprMas)
            acTbl.SetTextString(1, 2, " " & sIn.Address)
            acTbl.SetTextString(2, 0, "CF nr.")
            acTbl.SetTextString(2, 1, sIn.CF)
            acTbl.SetTextString(2, 2, "UAT")
            acTbl.SetTextString(2, 3, sIn.UAT)
            acBlkTblRec.AppendEntity(acTbl)
            acTrans.AddNewlyCreatedDBObject(acTbl, True)
            obj.oiTBTOP = acTbl.ObjectId
            acTbl = Nothing




            '// middle table
            i = 3 '// fixed part for parcels
            If (sIn.Parcels Is Nothing) Then
                i = i + 1
            Else
                i = i + sIn.Parcels.Length
            End If
            If (sIn.Constr Is Nothing) Then
                '// entire section is missing
            Else
                i = i + 3 + sIn.Constr.Length
            End If
            acTbl = New Table
            acTbl.SetDatabaseDefaults()
            acTbl.IsHeaderSuppressed = True
            acTbl.IsTitleSuppressed = True
            acTbl.NumRows = i
            acTbl.NumColumns = 5
            For i = 0 To acTbl.NumRows - 1
                For j = 0 To 4
                    acTbl.SetTextHeight(i, j, sIn.ppr.TextH)
                    acTbl.SetAlignment(i, j, CellAlignment.MiddleCenter)
                Next
                acTbl.SetRowHeight(i, sIn.ppr.TextH * sIn.adv.dRoR_1)
            Next
            acTbl.SetColumnWidth(0, sIn.ppr.TextH * sIn.adv.dClR_Mid_1)
            acTbl.SetColumnWidth(1, sIn.ppr.TextH * sIn.adv.dClR_Mid_2)
            acTbl.SetColumnWidth(2, sIn.ppr.TextH * sIn.adv.dClR_Mid_3)
            acTbl.SetColumnWidth(3, sIn.ppr.TextH * sIn.adv.dClR_Mid_4)
            '// last column fills the page
            acTbl.SetColumnWidth(4, (dWUsable - _
                                        (sIn.adv.dClR_Mid_1 + _
                                        sIn.adv.dClR_Mid_2 + _
                                        sIn.adv.dClR_Mid_3 + _
                                        sIn.adv.dClR_Mid_4) * _
                                        sIn.ppr.TextH))

            acTbl.Position = New Point3d(0, 40, 0)
            acTbl.Layer = sIn.ppr.Ly_Tbl

            '// second row has special treatement
            acTbl.SetRowHeight(1, sIn.adv.dRoR_2 * sIn.ppr.TextH)

            '// A. Date referitoare...
            Cellreg = New TableRegion(0, 0, 0, 4)
            acTbl.MergeCells(Cellreg)
            acTbl.SetTextString(0, 0, "A. Date referitoare la teren")
            acTbl.SetTextString(1, 0, "Nr. parcela")
            acTbl.SetTextString(1, 1, "Categ. de fol.")
            acTbl.SetTextString(1, 2, "Suprafata (mp)")
            acTbl.SetTextString(1, 3, "Val. de impozitare (lei)")
            acTbl.SetTextString(1, 4, "Mentiuni")
            i = 1
            dDbl1 = 0
            If (sIn.Parcels IsNot Nothing) Then
                For i = 0 To sIn.Parcels.Length - 1
                    acTbl.SetTextString(2 + i, 0, sIn.Parcels(i).Name)
                    acTbl.SetTextString(2 + i, 1, sIn.Parcels(i).Categ)
                    acTbl.SetTextString(2 + i, 2, sIn.Parcels(i).Supr)
                    acTbl.SetTextString(2 + i, 3, sIn.Parcels(i).ValImp)
                    acTbl.SetTextString(2 + i, 4, sIn.Parcels(i).Tip)
                    dDbl2 = 0
                    If CMain.GetDbl(sIn.Parcels(i).Supr, dDbl2) Then
                        dDbl1 = dDbl1 + dDbl2
                    End If
                Next
                i = sIn.Parcels.Length
            End If
            acTbl.SetTextString(2 + i, 0, "Total")
            acTbl.SetTextString(2 + i, 1, "-")
            acTbl.SetTextString(2 + i, 2, dDbl1.ToString("0"))
            acTbl.SetTextString(2 + i, 3, "-")
            acTbl.SetTextString(2 + i, 4, "-")

            If (sIn.Constr IsNot Nothing) Then
                i = i + 3
                '// second row has special treatment
                acTbl.SetRowHeight(i + 1, sIn.ppr.TextH * sIn.adv.dRoR_2)
                '//B. Date referitoare...
                Cellreg = New TableRegion(i, 0, i, 4)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(i + 0, 0, "B. Date referitoare la constructii")
                acTbl.SetTextString(i + 1, 0, "Cod")
                acTbl.SetTextString(i + 1, 1, "Cod grupa destinatie")
                acTbl.SetTextString(i + 1, 2, "Suprafata (mp)")
                acTbl.SetTextString(i + 1, 3, "Valoarea de impozitare (lei)")
                acTbl.SetTextString(i + 1, 4, "Mentiuni")
                dDbl1 = 0
                For j = 0 To sIn.Constr.Length - 1
                    acTbl.SetTextString(2 + i, 0, sIn.Constr(j).Code)
                    acTbl.SetTextString(2 + i, 1, sIn.Constr(j).Categ)
                    acTbl.SetTextString(2 + i, 2, sIn.Constr(j).Supr)
                    acTbl.SetTextString(2 + i, 3, sIn.Constr(j).ValImp)
                    acTbl.SetTextString(2 + i, 4, sIn.Constr(j).Tip)
                    dDbl2 = 0
                    If CMain.GetDbl(sIn.Constr(j).Supr, dDbl2) Then
                        dDbl1 = dDbl1 + dDbl2
                    End If
                    i = i + 1
                Next
                acTbl.SetTextString(2 + i, 0, "Total")
                acTbl.SetTextString(2 + i, 1, "-")
                acTbl.SetTextString(2 + i, 2, dDbl1.ToString("0"))
                acTbl.SetTextString(2 + i, 3, "-")
                acTbl.SetTextString(2 + i, 4, "-")
            End If
            acBlkTblRec.AppendEntity(acTbl)
            acTrans.AddNewlyCreatedDBObject(acTbl, True)
            obj.oiTBMID = acTbl.ObjectId
            acTbl = Nothing



            acTbl = New Table
            acTbl.SetDatabaseDefaults()
            acTbl.IsHeaderSuppressed = True
            acTbl.IsTitleSuppressed = True
            acTbl.Position = New Point3d(0, 0, 0)
            acTbl.Layer = sIn.ppr.Ly_Tbl

            Dim sSet As String = vbNewLine & "Executat: "
            If (String.IsNullOrEmpty(sIn.adv.sExecname) = False) Then
                sSet = sSet & sIn.adv.sExecname
            End If
            sSet = sSet & vbNewLine & "Data: "
            If (String.IsNullOrEmpty(sIn.adv.sData) = False) Then
                sSet = sSet & sIn.adv.sData
            Else
                sSet = sSet & sMonths(Today.Month-1) & " " & Year(Today).ToString
            End If


            If (iRows < 8) Then
                '// single coord column
                acTbl.NumRows = 4 + iRows
                acTbl.NumColumns = 4
                iRwExc = acTbl.NumRows \ 2 + 1
                iRwConf = acTbl.NumRows - iRwExc
                Dim dRowHSz = sIn.ppr.TextH * sIn.adv.dRoR_1
                '// enshure a minimum height (for 2.5 is 80)
                If (dRowHSz * acTbl.NumRows < sIn.ppr.TextH * sIn.adv.dBtm_MinH) Then
                    dRowHSz = (sIn.ppr.TextH * sIn.adv.dBtm_MinH) / acTbl.NumRows
                End If
                For i = 0 To acTbl.NumRows - 1
                    For j = 0 To 3
                        acTbl.SetTextHeight(i, j, sIn.ppr.TextH)
                        acTbl.SetAlignment(i, j, CellAlignment.MiddleCenter)
                    Next
                    acTbl.SetRowHeight(i, dRowHSz)
                Next
                '// deal with widths
                acTbl.SetColumnWidth(0, sIn.ppr.TextH * sIn.adv.dClR_Btm_Idx) '// index
                acTbl.SetColumnWidth(1, sIn.ppr.TextH * sIn.adv.dCLR_Btm_Coord) '// X
                acTbl.SetColumnWidth(2, sIn.ppr.TextH * sIn.adv.dCLR_Btm_Coord) '// Y
                acTbl.SetColumnWidth(3, dWUsable - _
                        (sIn.adv.dClR_Btm_Idx + _
                        sIn.adv.dCLR_Btm_Coord * 2) * _
                        sIn.ppr.TextH)


                Cellreg = New TableRegion(0, 0, 0, 2)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(0, 0, "INVENTAR DE COORDONATE")
                Cellreg = New TableRegion(1, 0, 1, 2)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(1, 0, "Sistem de proiectie STEREO '70")
                acTbl.SetTextString(2, 0, "Pct.")
                acTbl.SetTextString(2, 1, "Nord (m)")
                acTbl.SetTextString(2, 2, "Est (m)")
                Cellreg = New TableRegion(3 + iRows, 0, 3 + iRows, 2)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(3 + iRows, 0, _
                                            "Suprafata masurata = " & sIn.SuprMas & vbNewLine & _
                                            "Suprafata din act = " & sIn.SuprAct)
                If (dRowHSz > sIn.ppr.TextH * sIn.adv.dRoR_2) Then
                    acTbl.SetRowHeight(3 + iRows, dRowHSz)
                Else
                    acTbl.SetRowHeight(3 + iRows, sIn.ppr.TextH * sIn.adv.dRoR_2)
                End if   

                Cellreg = New TableRegion(0, 3, iRwExc - 1, 3)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(0, 3, sSet)
                acTbl.SetAlignment(0, 3, CellAlignment.TopCenter)
                Cellreg = New TableRegion(iRwExc, 3, acTbl.NumRows - 1, 3)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(iRwExc, 3, vbNewLine & _
                                            "Se confirma suprafata din masuratori si" & vbNewLine & _
                                            "introducerea imobilului in baza de data")
                acTbl.SetAlignment(iRwExc, 3, CellAlignment.TopCenter)

                If (sIn.Coord IsNot Nothing) Then
                    For i = 0 To sIn.Coord.Length - 1
                        acTbl.SetTextString(i + 3, 0, _
                                 sIn.Coord(i).PtName)
                        acTbl.SetTextString(i + 3, 1, _
                                 sIn.Coord(i).dN.ToString(sIn.CoordF_XY))
                        acTbl.SetTextString(i + 3, 2, _
                                 sIn.Coord(i).dE.ToString(sIn.CoordF_XY))
                    Next
                End If
            Else
                '// double coord column
                acTbl.NumRows = 4 + (iRows \ 2)
                acTbl.NumColumns = 8
                iRwExc = acTbl.NumRows \ 2 + 1
                iRwConf = acTbl.NumRows - iRwExc
                Dim dRowHSz = sIn.ppr.TextH * sIn.adv.dRoR_1
                '// enshure a minimum height 
                If (dRowHSz * acTbl.NumRows < sIn.ppr.TextH * sIn.adv.dBtm_MinH) Then
                    dRowHSz = (sIn.ppr.TextH * sIn.adv.dBtm_MinH) / acTbl.NumRows
                End If

                For i = 0 To acTbl.NumRows - 1
                    For j = 0 To 7
                        acTbl.SetTextHeight(i, j, sIn.ppr.TextH)
                        acTbl.SetAlignment(i, j, CellAlignment.MiddleCenter)
                    Next
                    acTbl.SetRowHeight(i, dRowHSz)
                Next
                '// deal with widths
                acTbl.SetColumnWidth(0, sIn.ppr.TextH * sIn.adv.dClR_Btm_Idx) '// index
                acTbl.SetColumnWidth(1, sIn.ppr.TextH * sIn.adv.dCLR_Btm_Coord) '// X
                acTbl.SetColumnWidth(2, sIn.ppr.TextH * sIn.adv.dCLR_Btm_Coord) '// Y
                acTbl.SetColumnWidth(3, sIn.ppr.TextH * sIn.adv.dClR_Btm_Sep) '// separator
                acTbl.SetColumnWidth(4, sIn.ppr.TextH * sIn.adv.dClR_Btm_Idx) '// index
                acTbl.SetColumnWidth(5, sIn.ppr.TextH * sIn.adv.dCLR_Btm_Coord) '// X
                acTbl.SetColumnWidth(6, sIn.ppr.TextH * sIn.adv.dCLR_Btm_Coord) '// Y
                '// 210 - 20 - 10 - 5*2 = 170 (total width) for a cell of 25
                acTbl.SetColumnWidth(7, dWUsable - _
                        (sIn.adv.dClR_Btm_Idx * 2 + _
                        sIn.adv.dCLR_Btm_Coord * 4 + _
                        sIn.adv.dClR_Btm_Sep) * _
                        sIn.ppr.TextH)

                Cellreg = New TableRegion(0, 0, 0, 6)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(0, 0, "INVENTAR DE COORDONATE")
                Cellreg = New TableRegion(1, 0, 1, 6)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(1, 0, "Sistem de proiectie STEREO '70")
                Cellreg = New TableRegion(3 + (iRows / 2), 0, 3 + (iRows / 2), 6)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(3 + (iRows / 2), 0, _
                                            "Suprafata masurata = " & sIn.SuprMas & vbNewLine & _
                                            "Suprafata din act = " & sIn.SuprAct)
                If (dRowHSz > sIn.ppr.TextH * sIn.adv.dRoR_2) Then
                    acTbl.SetRowHeight(3 + (iRows / 2), dRowHSz)
                Else
                    acTbl.SetRowHeight(3 + (iRows / 2), sIn.ppr.TextH * sIn.adv.dRoR_2)
                End if  

                acTbl.SetTextString(2, 0, "Pct.")
                acTbl.SetTextString(2, 1, "Nord (m)")
                acTbl.SetTextString(2, 2, "Est (m)")
                acTbl.SetTextString(2, 4, "Pct.")
                acTbl.SetTextString(2, 5, "Nord (m)")
                acTbl.SetTextString(2, 6, "Est (m)")


                Cellreg = New TableRegion(0, 7, iRwExc - 1, 7)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(0, 7, sSet)
                acTbl.SetAlignment(0, 7, CellAlignment.TopCenter)

                Cellreg = New TableRegion(iRwExc, 7, acTbl.NumRows - 1, 7)
                acTbl.MergeCells(Cellreg)
                acTbl.SetTextString(iRwExc, 7, vbNewLine & _
                                            "Se confirma suprafata din masuratori si" & vbNewLine & _
                                            "introducerea imobilului in baza de data")
                acTbl.SetAlignment(iRwExc, 7, CellAlignment.TopCenter)


                j = 3
                For i = 0 To iRows / 2 - 1
                    acTbl.SetTextString(j, 0, _
                             sIn.Coord(i).PtName)
                    acTbl.SetTextString(j, 1, _
                             sIn.Coord(i).dN.ToString("0.000"))
                    acTbl.SetTextString(j, 2, _
                             sIn.Coord(i).dE.ToString("0.000"))
                    j = j + 1
                Next
                j = 3
                For i = iRows / 2 To sIn.Coord.Length - 1
                    acTbl.SetTextString(j, 4, _
                             sIn.Coord(i).PtName)
                    acTbl.SetTextString(j, 5, _
                             sIn.Coord(i).dN.ToString("0.000"))
                    acTbl.SetTextString(j, 6, _
                             sIn.Coord(i).dE.ToString("0.000"))
                    j = j + 1
                Next
            End If
            acBlkTblRec.AppendEntity(acTbl)
            acTrans.AddNewlyCreatedDBObject(acTbl, True)
            obj.oiTBBTM = acTbl.ObjectId
            acTbl = Nothing

            bRet = True
        Catch ex As System.Exception
            CMain.DebugException(ex)
            bRet = False
        End Try
        Return bRet
    End Function
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
    '// ROOT. Creates a PAD based on input data
    Public Shared Function Create_PAD( _
        ByRef acDoc As Document, _
        ByRef sIn As PADDATA) As Boolean


        Dim bRet As Boolean = False
        Dim obj As PADOBJ = Nothing



        Using acTrans As Transaction = _
                acDoc.Database.TransactionManager.StartTransaction()
            Try

                '// get the size of the paper
                Dim pprty As Integer
                pprty = GetPprType(sIn.ppr.Format)

                '// check advanced settings for sanity
                If sIn.adv.dTxR_Anexa < CMain.MARGIN Then sIn.adv.dTxR_Anexa = 0.9
                If sIn.adv.dTxR_Title < CMain.MARGIN Then sIn.adv.dTxR_Title = 1.2
                If sIn.adv.dTxR_Scale < CMain.MARGIN Then sIn.adv.dTxR_Scale = 1
                If sIn.adv.dRoR_1 < CMain.MARGIN Then sIn.adv.dRoR_1 = 1.3
                If sIn.adv.dRoR_2 < CMain.MARGIN Then sIn.adv.dRoR_2 = 1.3
                If sIn.adv.dClR_Top_1 < CMain.MARGIN Then sIn.adv.dClR_Top_1 = 10
                If sIn.adv.dCLR_Top_2 < CMain.MARGIN Then sIn.adv.dCLR_Top_2 = 10
                If sIn.adv.dClR_Top_3 < CMain.MARGIN Then sIn.adv.dClR_Top_3 = 8
                If sIn.adv.dClR_Mid_1 < CMain.MARGIN Then sIn.adv.dClR_Mid_1 = 10
                If sIn.adv.dClR_Mid_2 < CMain.MARGIN Then sIn.adv.dClR_Mid_2 = 10
                If sIn.adv.dClR_Mid_3 < CMain.MARGIN Then sIn.adv.dClR_Mid_3 = 10
                If sIn.adv.dClR_Mid_4 < CMain.MARGIN Then sIn.adv.dClR_Mid_4 = 10
                If sIn.adv.dClR_Btm_Idx < CMain.MARGIN Then sIn.adv.dClR_Btm_Idx = 6
                If sIn.adv.dCLR_Btm_Coord < CMain.MARGIN Then sIn.adv.dCLR_Btm_Coord = 8
                If sIn.adv.dClR_Btm_Sep < CMain.MARGIN Then sIn.adv.dClR_Btm_Sep = 0.2
                If sIn.adv.dBtm_MinH < sIn.ppr.TextH * 7 Then sIn.adv.dBtm_MinH = sIn.ppr.TextH * 7
                If sIn.adv.dWidth = 0 Then
                    If (pprty <= 3) Then
                        If (sIn.ppr.Po) Then
                            sIn.adv.dWidth = PaperTy(3).iW
                        Else
                            sIn.adv.dWidth = PaperTy(3).iH
                        End If
                    Else
                        sIn.adv.dWidth = PaperTy(4).iW
                    End If
                    sIn.adv.dWidth = sIn.adv.dWidth - _
                                    sIn.adv.dB_Al_H * 2 - _
                                    sIn.adv.dB_Left - _
                                    sIn.adv.dB_Right
                End If



                '// create a new layout
                If (Create_lAY(acDoc, acTrans, sIn.ppr) = False) Then
                    CMain.AlertUser("Foaia nu a putut fi generata.")
                    acTrans.Abort()
                    Exit Try
                End If

                '// Get active space (is just a block)
                Dim acBlkSpace As BlockTableRecord = DirectCast( _
                    acTrans.GetObject( _
                        acDoc.Database.CurrentSpaceId, _
                        OpenMode.ForWrite),  _
                    BlockTableRecord)

                '// create graphical components
                If (Create_PAD_Comp(acBlkSpace, acTrans, sIn, obj) = False) Then
                    CMain.AlertUser("Elementele componente ale foii nu au putut fi create.")
                    acTrans.Abort()
                    Exit Try
                End If

                '// arrange components
                If (Arrange_PAD_Generic(acBlkSpace,  acTrans, sIn, obj, pprty) = False) Then
                    CMain.AlertUser("Elementele componente ale foii nu au putut fi aranjate.")
                    acTrans.Commit()
                    Exit Try
                End If

                '// a good finish
                bRet = True
                acTrans.Commit()
            Catch ex As System.Exception
                acTrans.Abort()
                CMain.DebugException(ex)
            End Try
        End Using '// acTrans
        If (bRet = True) Then
            Application.AcadApplication.ZoomExtents()
        End If
        GC.Collect()
        GC.WaitForPendingFinalizers()
        Return bRet
    End Function
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
    '// Arrange PAD items for an A4 portrait layout
    Private Shared Function Arrange_PAD_Generic ( _
        ByRef acBlkTblRec As BlockTableRecord, _
        ByRef acTrans As Transaction, _
        ByRef sIn As PADDATA, _
        ByRef obj As PADOBJ, _
        ByVal pprty As Integer) As Boolean


        Dim bRet As Boolean = False
        Dim acPly As Polyline = Nothing
        Dim acTxt As DBText = Nothing
        Dim acTbl As Table = Nothing
        Dim acVp As Viewport = Nothing

        ' TODO
        ' space between bottom table and bottom margin
        ' space between top table and viewport (space arround viewport)


        Dim dAux_V As Double
        Dim dAux_VBtm As Double
        Dim dAux_H As Double

        Dim dPprW As Double
        Dim dPprH As Double

        Dim tbAlV As Double = sIn.adv.dB_Al_V * sIn.ppr.TextH
        Dim tbAlH As Double = sIn.adv.dB_Al_H * sIn.ppr.TextH

        ' Get the PlotInfo from the layout
        Dim acLayout as Layout= DirectCast( _
            acTrans.GetObject( _
                LayoutManager.Current.GetLayoutId( _
                    LayoutManager.Current.CurrentLayout), _
                         OpenMode.ForWrite),  _
            Layout)
        Dim dX_off as Double = -1*acLayout.PlotPaperMargins.MinPoint.X
        Dim dY_off As Double = -1*acLayout.PlotPaperMargins.MinPoint.Y

        If (sIn.ppr.Po) then
            dPprW = acLayout.PlotPaperSize.X
            dPprH = acLayout.PlotPaperSize.Y
        Else
            dPprH = acLayout.PlotPaperSize.X
            dPprW = acLayout.PlotPaperSize.Y
        End If

        'If (sIn.ppr.Po) then
        '    dPprW = PaperTy(pprty).iW
        '    dPprH = PaperTy(pprty).iH
        'Else
        '    dPprH = PaperTy(pprty).iW
        '    dPprW = PaperTy(pprty).iH
        'End If

        Try
            '// create a bounding polyline
            acPly = New Polyline(4)
            acPly.SetDatabaseDefaults()
            acPly.Layer = sIn.ppr.Ly_Var
            acPly.AddVertexAt(0, New Point2d( _
                              dX_off + sIn.adv.dB_Left, _
                              dY_off + dPprH - sIn.adv.dB_Top), _
                              0, 0, 0) ' top left
            acPly.AddVertexAt(1, New Point2d( _
                              dX_off + dPprW - sIn.adv.dB_Right, _
                              dY_off + dPprH - sIn.adv.dB_Top), _
                              0, 0, 0) ' top right
            acPly.AddVertexAt(2, New Point2d( _
                              dX_off + dPprW - sIn.adv.dB_Right, _
                              dY_off + sIn.adv.dB_Bottom), _
                              0, 0, 0) ' bottom right
            acPly.AddVertexAt(3, New Point2d( _
                              dX_off + sIn.adv.dB_Left, _
                              dY_off + sIn.adv.dB_Bottom), _
                              0, 0, 0) ' bottom left
            acPly.Closed = True
            acBlkTblRec.AppendEntity(acPly)
            acTrans.AddNewlyCreatedDBObject(acPly, True)
            acPly = Nothing

            dAux_H = dX_off + (dPprW - sIn.adv.dB_Right - sIn.adv.dB_Left) / 2 + _
                        sIn.adv.dB_Left

             '// move bottom table in place
            acTbl = DirectCast( _
                acTrans.GetObject(obj.oiTBBTM, OpenMode.ForWrite), _
                Table)
            dAux_VBtm = dY_off + sIn.adv.dB_Bottom + acTbl.Height + tbAlV
            acTbl.Position = New Point3d(dAux_H - acTbl.Width / 2, _
                                         dAux_VBtm, 0)
            acTbl = Nothing

             '// move middle table in place
            acTbl = DirectCast( _
                acTrans.GetObject(obj.oiTBMID, OpenMode.ForWrite), _
                Table)
            dAux_VBtm = dAux_VBtm + acTbl.Height
            acTbl.Position = New Point3d(dAux_H - acTbl.Width / 2, dAux_VBtm, 0)
            acTbl = Nothing
            dAux_VBtm = dAux_VBtm + tbAlV

            '// move "Anexa" in place
            acTxt = DirectCast( _
                acTrans.GetObject(obj.oiANX, OpenMode.ForWrite), _
                DBText)
            dAux_V = dY_off + dPprH - sIn.adv.dB_Top - sIn.adv.dTxR_Al * sIn.ppr.TextH
            acTxt.VerticalMode = TextVerticalMode.TextTop
            acTxt.HorizontalMode = TextHorizontalMode.TextRight
            acTxt.AlignmentPoint = New Point3d( _
                          dX_off + dPprW - sIn.adv.dB_Right - sIn.adv.dTxR_Al * sIn.ppr.TextH, _
                          dAux_V, _
                          0)
            dAux_V = dAux_V - acTxt.Height
            acTxt = Nothing

            dAux_V = dAux_V - sIn.adv.dTxR_Al * sIn.ppr.TextH


            '// move title in place
            acTxt = DirectCast( _
                acTrans.GetObject(obj.oiTITLE, OpenMode.ForWrite), _
                DBText)
            acTxt.VerticalMode = TextVerticalMode.TextVerticalMid
            acTxt.HorizontalMode = TextHorizontalMode.TextCenter
            acTxt.AlignmentPoint = New Point3d(dAux_H, dAux_V - acTxt.Height / 2, 0)
            dAux_V = dAux_V - acTxt.Height
            acTxt = Nothing

            dAux_V = dAux_V - sIn.adv.dTxR_Al * sIn.ppr.TextH


            '// move scale in place
            acTxt = DirectCast( _
                acTrans.GetObject(obj.oiSCALE, OpenMode.ForWrite), _
                DBText)
            acTxt.VerticalMode = TextVerticalMode.TextVerticalMid
            acTxt.HorizontalMode = TextHorizontalMode.TextCenter
            acTxt.AlignmentPoint = New Point3d(dAux_H, dAux_V - acTxt.Height / 2, 0)
            dAux_V = dAux_V - acTxt.Height
            acTxt = Nothing

            dAux_V = dAux_V - sIn.adv.dTxR_Al * sIn.ppr.TextH

            '// move top table in place
            acTbl = DirectCast( _
                acTrans.GetObject(obj.oiTBTOP, OpenMode.ForWrite),  _
                Table)
            acTbl.Position = New Point3d(dAux_H - acTbl.Width / 2, dAux_V, 0)
            dAux_V = dAux_V - acTbl.Height
            acTbl = Nothing
            dAux_V = dAux_V - tbAlV

            '// move viewport in place
            If (dAux_VBtm < dAux_V) Then

                Dim dot As DrawOrderTable = _
                    acTrans.GetObject(acBlkTblRec.DrawOrderTableId, OpenMode.ForWrite)
                Dim oic As New ObjectIdCollection
                acVp = DirectCast( _
                    acTrans.GetObject(obj.oiVP, OpenMode.ForWrite),  _
                    Viewport)
                acVp.Width = (dPprW - sIn.adv.dB_Right - sIn.adv.dB_Left - tbAlH * 2)
                acVp.Height = dAux_V - dAux_VBtm

                acPly = New Polyline(4)
                acPly.SetDatabaseDefaults()
                acPly.Layer = sIn.ppr.Ly_Var
                acPly.AddVertexAt(0, New Point2d( _
                                  dAux_H - acVp.Width / 2, _
                                  dAux_VBtm + acVp.Height), _
                                  0, 0, 0) ' top left
                acPly.AddVertexAt(1, New Point2d( _
                                  dAux_H + acVp.Width / 2, _
                                  dAux_VBtm + acVp.Height), _
                                  0, 0, 0) ' top right
                acPly.AddVertexAt(2, New Point2d( _
                                  dAux_H + acVp.Width / 2, _
                                  dAux_VBtm), _
                                  0, 0, 0) ' bottom right
                acPly.AddVertexAt(3, New Point2d( _
                                  dAux_H - acVp.Width / 2, _
                                  dAux_VBtm), _
                                  0, 0, 0) ' bottom left
                acPly.Closed = True
                acBlkTblRec.AppendEntity(acPly)
                acTrans.AddNewlyCreatedDBObject(acPly, True)

                acVp.CenterPoint = New Point3d( _
                    dAux_H, _
                    dAux_VBtm + acVp.Height / 2, _
                    0)
                oic.Add(acVp.ObjectId)
                dot.MoveToTop(oic)
                oic.Dispose
                oic = Nothing
                dot = Nothing
                acPly = Nothing
                acVp = Nothing

            End If
        bRet = True
        Catch ex As System.Exception
            If (acPly isnot Nothing) then
                acPly.Dispose()
                acPly = Nothing
            End If
            CMain.DebugException(ex)
            bRet = False
        End Try
        GC.Collect
        GC.WaitForPendingFinalizers()
        Return bRet

    End Function
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
    '// Save pad data
    Public Shared Sub Save_Pad_To_File(ByRef sIn As PADDATA, _
                                       ByRef sFile As String)

        ' SERIALIZE
        Try
            Dim fs As FileStream = New FileStream(sFile, FileMode.Create)
            Dim xs As XmlSerializer = New XmlSerializer(GetType(PADDATA))
            xs.Serialize(fs, sIn)
            fs.Close()
        Catch ex As System.Exception
            CMain.DebugException(ex)
        End Try
    End Sub
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
    '// Save pad data
    Public Shared Sub Load_Pad_From_File(ByRef sIn As PADDATA, _
                                       ByRef sFile As String)

        ' DESERIALIZE
        Dim fs As FileStream = New FileStream(sFile, FileMode.Open)
        Dim xs As XmlSerializer = New XmlSerializer(GetType(PADDATA))
        sIn = CType(xs.Deserialize(fs), PADDATA)
        fs.Close()
    End Sub
    '// ===================================================================== '


#End Region


#Region "C O M M A N D S"


    '// --------------------------------------------------------------------- '
    <CommandMethod(sCMD_PAD)> _
    Public Sub Show_PAD()
        Try

            Dim StgD As CD_PAD = New CD_PAD
            Application.ShowModelessDialog(StgD)
        Catch ex As System.Exception
            CMain.PopUpExc()
            CMain.DebugException(ex)
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    <CommandMethod(sCMD_PS)> _
    Public Sub Show_PS()
        Try

            Dim StgD As CD_PS = New CD_PS
            Application.ShowModelessDialog(StgD)
        Catch ex As System.Exception
            CMain.PopUpExc()
            CMain.DebugException(ex)
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    <CommandMethod(sCMD_SETTINGS)> _
    Public Sub Show_Settings()
        Try

            Dim StgD As CST_RO_Tables = New CST_RO_Tables
            Application.ShowModelessDialog(StgD)
        Catch ex As System.Exception
            CMain.PopUpExc()
            CMain.DebugException(ex)
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '

#End Region

End Class
'//  CLASS    =============================================================== '
'//
'//
'//
'//
'//  FUNCTIONS    ----------------------------------------------------------- '

'//  FUNCTIONS    =========================================================== '
'//
'//
'//
'//
'// ------------------------------------------------------------------------- '
'// ========================================================================= '
#End If